package net.chrisrichardson.ec2deployer.cluster

import org.apache.commons.logging.*
import net.chrisrichardson.ec2deployer.applications.JmeterApplication
import net.chrisrichardson.ec2deployer.applications.JmeterLogAnalyzer
import net.chrisrichardson.ec2deployer.core.EC2Server
import net.chrisrichardson.ec2deployer.core.CloudManager

class JmeterTier extends AbstractTier {

    Log logger = LogFactory.getLog(getClass())

    ClusterSpec spec

    AppServerTier appServerTier
    WebServerTier webServerTier
    DatabaseTier databaseTier

    JmeterApplication jmeter
    TerracottaTier terracottaTier
    
    JmeterTier() {}
    
    JmeterTier(CloudManager ec2, spec, appServerTier, webServerTier, databaseTier, terracottaTier) {
        super(ec2)
        this.spec = spec
        this.appServerTier = appServerTier
        this.webServerTier = webServerTier
        this.databaseTier = databaseTier
        this.terracottaTier = terracottaTier
    }

    def saveState(result) {
        if (jmeter)
            result.put("jmeter", [jmeter.host.instanceId])
    }

    def restoreState(serverState) {
        this.jmeter = restoreJmeterServer(serverState["jmeter"])
    }

    def restoreJmeterServer(previousInstanceId) {
        if (previousInstanceId)
            return new JmeterApplication(ec2.findInstance(previousInstanceId[0]), webServerTier)
    }

    void performStart() {
    }

    def assignHosts(hosts) {
        jmeter = new JmeterApplication(hosts["jmeter"], webServerTier)
    }

    void loadTest(String jmxFileName, List<Integer> threadCounts, List<String> dataFiles) {
        def cpuCount = appServerTier.numberOfTomcats
        def prefix = cpuCount.toString() + "-"
        threadCounts.each {threadCount ->
            logger.debug("Tomcats = ${appServerTier.numberOfTomcats}, Threads = $threadCount")
            allSarMonitors*.start()
            def localResultsFile = jmeter.runOnce(jmxFileName, prefix, threadCount, dataFiles)
            allSarMonitors*.stop()
            def analyzer = new JmeterLogAnalyzer(localResultsFile)
            logger.debug("**************")
            analyzer.analyze()
            logger.info "**** generating report to target dir"
            Map hosts = getHostsSarMonitors()
            analyzer.report("target/${prefix}-$threadCount-report.xml", hosts, cpuCount, threadCount)
            logger.debug "**** done generating report"
        }
    }

    def getHostsSarMonitors() {
        Map hosts = new LinkedHashMap()
        hosts["database"] = databaseTier.sarMonitor
        def slaveIdx = 0;
        databaseTier.sarMonitorsForSlaves.each {sarMonitor ->
            hosts["slave" + slaveIdx] = sarMonitor
            slaveIdx = slaveIdx + 1
        }
        def tcIdx = 0;
        terracottaTier.sarMonitors.each {sarMonitor ->
            hosts["terracotta" + tcIdx] = sarMonitor
            tcIdx = tcIdx + 1
        }
        def tomcatIdx = 0;
        appServerTier.sarMonitors.each {sarMonitor ->
            hosts["tomcat" + tomcatIdx] = sarMonitor
            tomcatIdx = tomcatIdx + 1
        }
        hosts["apache"] = webServerTier.sarMonitor
        hosts["jmeter"] = jmeter.sarMonitor
        hosts
    }

    List<EC2Server> getServers() {
        [jmeter.host]
    }

    def getAllSarMonitors() {
        new HashSet([this.sarMonitor] + [webServerTier.sarMonitor] + terracottaTier.sarMonitors + appServerTier.sarMonitors + [databaseTier.sarMonitor] + databaseTier.sarMonitorsForSlaves)
    }


    def getSarMonitor() {
        jmeter.sarMonitor
    }

}
